package de.unibi.comet.tools;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import de.unibi.comet.ac.AbelianPattern;
import de.unibi.comet.fa.Alphabet;
import de.unibi.comet.fa.DnaMotifParser;
import de.unibi.comet.util.Log;

public class abelian_assess_pattern {

	public static void usage() {
		System.out.println("usage: abelian <genome> <patternfile>");
		System.out.println("   <genome> file containing the plain (not fasta) genome");
		System.out.println("   <patternfile> file containing the abelian patterns to investigate");
		System.exit(1);
	}

	public static double[] getEmpiricDistribution(Alphabet alphabet, String s) {
		Log.getInstance().startTimer();
		double[] freq = new double[alphabet.size()];
		for (int i=0; i<s.length(); ++i) {
			freq[alphabet.getIndex(s.charAt(i))]+=1;
		}
		for (int i=0; i<freq.length; ++i) {
			freq[i]/=(double)s.length();
		}
		Log.getInstance().stopTimer("Determine empiric distribution");
		return freq;
	}
	
	public static void main(String[] args) {
		if (args.length!=2) usage();
		
		String genome = null;
		FileInputStream genomeFile = null;
		try {
			genomeFile = new FileInputStream(args[0]);
		} catch (FileNotFoundException e) {
			System.out.println("File not found, sorry!");
			System.exit(1);
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(genomeFile));
		try {
			String line = br.readLine();
			if (line==null) {
				System.out.println("Couldn't read cg genome");
				System.exit(1);
			}
			genome=line;
			System.out.println(String.format("Read genome: %d characters", genome.length()));
		} catch (IOException e) {
			System.out.println("I/O failure, sorry!");
			System.exit(1);
		}
		
		FileInputStream patternFile = null;
		try {
			patternFile = new FileInputStream(args[1]);
		} catch (FileNotFoundException e) {
			System.out.println("File not found, sorry!");
			System.exit(1);
		}
		br = new BufferedReader(new InputStreamReader(patternFile));
		ArrayList<String> l = new ArrayList<String>();
		try {
			while (true) {
				String line = br.readLine();
				if (line==null) break;
				l.add(line);
//				System.out.printf("line: %s\n",line);
			}
		} catch (IOException e) {
			System.out.println("I/O failure, sorry!");
			System.exit(1);
		}

		Log.getInstance().setTimingActive(true);
		// Log.getInstance().setLogLevel(Log.Level.INSANE);
		Log.getInstance().setLogLevel(Log.Level.EVERYTHING);

		Alphabet alphabet = DnaMotifParser.getDnaAlphabet();
		double[] charDist = getEmpiricDistribution(alphabet, genome);
		
		for (String s : l) {
			Log.getInstance().startTimer();
			AbelianPattern ap = new AbelianPattern(s);
			long stringCount = ap.countAllStrings();
			System.out.println(String.format("abelian pattern: %s --> %d strings", ap.toString(), stringCount));
			double expectation = genome.length() - ap.length() +1;
			expectation*=stringCount;
			int[] frequencies = ap.getFrequencies();
			for (int c=0; c<frequencies.length; ++c) {
				if (frequencies[c]==0) continue;
				double charProb=charDist[alphabet.getIndex((char)c)];
				for (int i=0; i<frequencies[c]; ++i) {
					expectation*=charProb;
				}
			}

			int matches = ap.match(genome, null);
				
			System.out.println(String.format("> %s %d %e %e %d", s, matches, expectation, ((double)matches)/expectation, stringCount));
			Log.getInstance().stopTimer("Whole experiment");
		}
	}
}
